# encoding:utf-8
#qpy:console
import time
import requests
import base64
import datetime
import requests
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:ECDHE:!COMPLEMENTOFDEFAULT"
import calendar
import json
import re
import copy

from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 #用于加密
from Crypto import Random
from Crypto import Hash

requests.packages.urllib3.disable_warnings()

class LianTong():
    
    pubkey = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDc+CZK9bBA9IU+gZUOc6\nFUGu7yO9WpTNB0PzmgFBh96Mg1WrovD1oqZ+eIF4LjvxKXGOdI79JRdve9\nNPhQo07+uqGQgE4imwNnRx7PFtCRryiIEcUoavuNtuRVoBAm6qdB0Srctg\naqGfLgKvZHOnwTjyNqjBUxzMeQlEC2czEMSwIDAQAB\n-----END PUBLIC KEY-----"
    session = requests.session()
    myUrl = {
        #post请求data 若没有则设置空字典
        #登录url
    	    "dlUrl" :[
    	        {
    	        	#手机服务密码登录有次数限制尽量使用token登录
    		   	    "title" : "手机服务密码登录url",
    		   	    "url": "https://m.client.10010.com/mobileService/login.htm",
    		   	    "data" :{
    		   	    	    "simCount" : "1",
    		   	    	    "yw_code" : "",
    		   	    	    "deviceOS" : "android10",
    		   	    	    "mobile" : "使用时设置",
    		   	    	    "netWay" : "4G",
    		   	    	    "deviceCode" : "a6774957a00841ffb293aeaca885afa6",
    		   	    	    "isRemberPwd" : "true",
    		   	    	    "version" : "android@8.0102",
    		   	    	    "deviceId" : "a6774957a00841ffb293aeaca885afa6",
    		   	    	    "password" : "使用时设置",
    		   	    	    "keyVersion" : "1",
    		   	    	    "pip" : "10.93.12.211",
    		   	    	    "provinceChanel" : "general",
    		   	    	    "appId" : "06eccb0b7c2fd02bc1bb5e8a9ca2874188bd8a8b08984ff9500748fd8c7c9a52b21d846ce6a48b3e20043ba2f5b750155216d556290845ff0183f6d098c32b620ea960b3caaf54cceb95f946dd356f46",
    		   	    	    "deviceModel" : "M2002J9E",
    		   	    	    "deviceBrand" : "Xiaomi",
    		   	    	    "timestamp" : time.strftime("YYYYMMDDHHmmss", time.localtime())
    		   	    	    },
    		   	    "type": "post"
    		   	    },
    		   	    {
    		   	    	#使用token登录
    		   	    "title" : "token登录url",
    		   	    "url": "https://m.client.10010.com/mobileService/onLine.htm",
    		   	    "data" :{
    		   	    	    "reqtime" : str(int(time.time())),
                 "appId" : "使用时设置",
                 "netWay" : "4G",
                 "deviceModel" : "M2002J9E",
                 "deviceCode" : "a6774957a00841ffb293aeaca885afa6",
                 "version" : "android@8.0102",
                 "deviceId" : "a6774957a00841ffb293aeaca885afa6",
                 "deviceBrand" : "Xiaomi",
                 "flushkey" : "1",
                 "token_online" : "使用时设置"
                },
    		   	    "type": "post"
    		   	    }
    		   	],
        #签到url
    		   "qdUrl" : {
    		       "title" : "签到url",
    		       "url": "https://act.10010.com/SigninApp/signin/daySign",
    		       "data": {},
    		       "type": "post"
    		       },
    		   #抽奖url
    		   "cjUrl" : [
    		       {
    		           "title" : "抽奖认证url",
    		           "url": "https://m.client.10010.com/dailylottery/static/textdl/userLogin",
    		           "params": {},
    		           "type": "get"
    		       },
    		       {
    		           	"title" : "抽奖url",
    		           	"url" : "https://m.client.10010.com/dailylottery/static/doubleball/choujiang",
    		           	"data" : {
    		               		"usernumberofjsp":"使用时设置"
    		           		},
    		           	"params": {},
    		           "type": "post"
    		       }
    		   ],
    		   	#4GB日流量url
    		   	"4GUrl" : [
    		   	    {
    		   	    	   "title" : "4GB日包看视频领流量url",
    		           "url": "https://act.10010.com/SigninApp/mySignin/addFlow",
    		           "data": {
    		   	            "stepflag": "22"
    		   	            },
    		           "type": "post"
    		   	    },
    		   	    {
    		   	       "title" : "4GB日包下软件领流量url",
    		           "url": "https://act.10010.com/SigninApp/mySignin/addFlow",
    		           "data": {
    		   	            "stepflag": "23"
    		   	            },
    		           "type": "post"
    		   	    }
    		   	],
    		   #查询流量url
    		   "cxUrl" :[
    		       {
    		   	        "title" : "查询流量使用url",
    		   	        "url": "https://m.client.10010.com/servicequerybusiness/operationservice/queryOcsPackageFlowLeftContentRevisedInJune",
    		   	        "data" :{
    		   	    	        "mobile":"使用时设置"
    		   	        	},
    		   	        "type": "post"
    		   	    }
    		   	],
    		   	#兑换日包url
    		   	"dhUrl" : [
    		       {
    		   	        "title" : "查询兑换参数使用url",
    		   	        "url": "https://m.client.10010.com/ChangeAccount/trafficController/myAccount.htm",
    		   	        "data" :{
    		   	    		        "queryType":"flow"
    		       	 	    },
    		         "type": "post"
    		   	    },
    		   	    {
    		   	    	    "title" : "兑换流量日包url",
    		   	        	"url": "https://m.client.10010.com/ChangeAccount/trafficController/exchangeDFlow.htm",
    		   	        	"data" :{
    		   	    		        "productId" : "用时再设置"
    		       	 	    },
    		         "type": "post"
    		        }
    		    ],
    		   #我的礼包url
    		   	"libaoUrl" : [
    		   	    {
    		   	    	   "title" : "查询礼包url",
    		           "url": "https://m.client.10010.com/myPrizeForActivity/mygiftbag.htm",
    		           "data": {
    		   	            "typeScreenCondition": "2",
    		   	            "category": "FFLOWPACKET",
    		   	            "pageSign": "1"
    		   	            },
    		           "type": "post"
    		   	    },
    		   	    {
    		   	       "title" : "激活礼包url",
    		           "url": "http://m.client.10010.com/myPrizeForActivity/myPrize/activationFlowPackages.htm",
    		           "data": {
    		   	             "activeCode": "使用时设置",
    		   	             "prizeRecordID": "使用时设置",
    		   	             "activeName": "使用时设置"
    		   	             },
    		           "type": "post"
    		   	    }
    		   	],
    		   "headers" : {
              "Accept": "application/json, text/plain, */*",
              "User-Agent": "Mozilla/5.0 (Linux; Android 10; M2002J9E Build/QKQ1.191222.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/81.0.4044.138 Mobile Safari/537.36; unicom{version:android@8.0805,desmobile:13233701306};devicetype{deviceBrand:Xiaomi,deviceModel:M2002J9E};{yw_code:}",
              "version": "android@10.0000",
              "content-type":"application/json"
         }
    		   
    	}
    def __init__(self,lianTong):
        for key,values in lianTong.items():
            setattr(self,key,values)
        #计数器
        self.num = 0
    
    def myRequests(self,url):
        
        url["headers"] = self.myUrl["headers"]
        try :    
            if url.get("type") == "post":
                html = self.session.post(url=url["url"],data=url.get("data"),params=url.get("params"),headers=url["headers"],verify=False)
            elif url.get("type") == "get":
                html = self.session.get(url=url["url"],headers=url["headers"],params=url.get("params"),verify=False)
        except Exception as e:
            print(str(e))
            self.num = self.num + 1
            if self.num <= 3:
                return self.myRequests(url)
            else:
                self.num = 0
                return None
        return html 
                  
    def rsaEncrypt(self,plain_text,pubkey):
        #先公钥加密
        cipher_pub_obj = PKCS1_v1_5.new(RSA.importKey(pubkey))
        _secret_byte_obj = cipher_pub_obj.encrypt(plain_text.encode('utf-8'))
        encrypted_text = str(base64.b64encode(_secret_byte_obj),encoding='utf-8')
        return encrypted_text    
        
    def login(self):
        
        url = self.myUrl["dlUrl"][1]
        
        url["data"]["appId"] = self.appId
        url["data"]["token_online"] = self.token_online
        html = self.myRequests(url)
        try:
            json = html.json()
            #text = json.get("disc").encode('raw_unicode_escape').decode()
            if json.get("code") == "0":
                print(self.mobile + "token登录成功")
                return 2
            else:
                print(self.mobile + "token登录失败")
                return self.loginPass()
        except Exception as e:
            print(self.mobile + "token登录失败")
            return self.loginPass()
            
                
    def loginPass(self): 
        self.session.close()
        self.session = requests.session()
        url = self.myUrl["dlUrl"][0]
        url["data"]["mobile"] = self.rsaEncrypt(self.mobile,self.pubkey)
        url["data"]["password"] = self.rsaEncrypt(self.password,self.pubkey)
        url["data"]["appId"] = self.appId
        html = self.myRequests(url)
        print(html.text)
        try:
            json = html.json()
            if json.get("code") == "0":
                print(self.mobile + "用户名登录成功")
                self.token_online = json["token_online"]
                return 1
            else:
                return 0
        except Exception as e:
            title = self.mobile + "用户名登录失败"
            print(title + str(e))    
            return 0    
    #签到          
    def qianDao(self):
        
        #签到
        url = self.myUrl["qdUrl"]
        json =  self.myRequests(url).json()
        print(json)
        if  json.get("status") == "0000" or json.get("status") == "0002":
            return "签到成功"
        else:
            return json.get("msg")          
              
    #抽奖   
    def chouJiang(self):
         
        #抽奖开始
        text = ""
        url = self.myUrl["cjUrl"][0]
        html = self.myRequests(url)
        
        pattern = r"[0-9a-zA-Z]{32}"
        usernumberofjsp = re.search(pattern,html.text).group()
        #多次抽奖 默认三次
        
        url = self.myUrl["cjUrl"][1].copy()
        url["params"]["usernumberofjsp"]= usernumberofjsp
        while True: 
            json = self.myRequests(url).json()
            print(json)
            text += str(json.get("RspMsg"))+ "  "
            time.sleep(3) 
            if json.get("Rsptype") == "6666":
                break 
            else:
                text += "抽奖成功"
        return text
    
    #4G七日流量包任务
    def qiRiLLB(self):
        
        
        #4GB七日流量包做任务的流量
        text = ""
        num = 3
        while num > 0:
            url = self.myUrl["4GUrl"][0]
            json = self.myRequests(url).json()
            num -=1
            if num !=0:
                time.sleep(3)
        num = 3
        while num > 0:
            url = self.myUrl["4GUrl"][1]
            json = self.myRequests(url).json()
            num -=1
            if num !=0:
                time.sleep(3)         
        if json.get("reason") == "00":
            text += "4GB七日流量包任务奖励领取成功 "
        else:
            text += "4GB七日流量包任务奖励领取失败 "
                             
        return text
        
    
    def getLibao(self):
        
           
        url = self.myUrl["libaoUrl"][0]
        url["headers"] = self.myUrl["headers"].copy()
        url["headers"]["content-type"] = "application/x-www-form-urlencoded"
        html = self.session.post(url=url["url"],data=url.get("data"),params=url.get("params"),headers=url["headers"],verify=False)
        text =  html.text
        data = self.findAll(text,["onclick=\"toDetailPage(",");","&nbsp;-&nbsp;","</p>","activeBt","p","<li>活动：","</li>"])
        if data[2] == []:
            return False
            
        myList = data[0][0:len(data[2])]
        timeList = data[1][0:len(data[2])]
        low = 88888888
        day_time = float(time.mktime(datetime.date.today().timetuple()))
        zuijin = ""
        for index in range(len(timeList)):
            timeArray = time.strptime(timeList[index], "%Y-%m-%d%H:%M:%S")
            timeStamp = float(time.mktime(timeArray))
            if timeStamp - day_time <  low:
                low = timeStamp - day_time
                zuijin = myList[index]
                zuijin += "," + data[3][index]
        data1 = zuijin.replace("'","").split(",")        
        libao = {}
        if data1 != []:
            libao["activeCode"] = data1[0]
            libao["prizeRecordID"] = data1[1]
            libao["activeName"] = data1[3]
       
        return libao   
        
    def jihuoLibao(self):
        
        libao = self.getLibao()
        if libao != False:
            url = self.myUrl["libaoUrl"][1]
            
            url["data"]= libao
            
            self.myRequests(url)
            return True
        else:
            return False
            
    def dhrb(self):
        state = False
        product = [
            {
            	    "productId": '21010621565413402',
                "productName": '2GB流量日包'
            },
            {
            	    "productId": '21010621461012371',
                "productName": '5GB流量日包'
            },
            {
            	    "productId": '21010621253114290',
                "productName": '10GB流量日包'
            }
        ]
        for i in range(len(product)):
            url = self.myUrl["dhUrl"][1].copy()
            url["data"]["productId"] = product[i]["productId"]
            url["data"] = json.dumps(url["data"])
            data = self.myRequests(url).json()
            if data["code"] == "0000":
                state = True
                break;
        return state
    
    def getUse(self):
        #月包使用和剩余
        use = 0
        remain = 0
        #日包剩余
        rbremain = 0
        rbuse = 0
        #免流使用量
        mlUse = 0
        state = False
        url = self.myUrl["cxUrl"][0]
        url["data"]["mobile"] = self.mobile
        data =  self.myRequests(url).json()
        myList = []
        keyList = ["details"]
        self.traversalDict(data,keyList,myList,self.traversalDict_func)   
        """
        定向包 resourceType : 13
        月包   resourceType : 01
        日包   resourceType : 26
        日租宝 resourceType : 46
        语音   resourceType : 02
        短信   resourceType : 04
        其他免流 None 设置为 00
        """
        #列表里面去重合并重复的
        myList = sorted(myList, key=lambda x : x['feePolicyId'])
        list1 = []
        list2 = []
        for index in range(len(myList)):
            feePolicyId = myList[index].get("feePolicyId")
            if feePolicyId not in list1:
                list1.append(feePolicyId)
                list2.append(myList[index])
            else:
                list2[-1]["use"] = round(float(list2[-1]["use"]) + float(myList[index]["use"]),2)
                list2[-1]["remain"] = round(float(list2[-1]["remain"]) + float(myList[index]["remain"]),2)
                list2[-1]["total"] = round(float(list2[-1]["total"]) + float(myList[index]["total"]),2)
        myList = list2
        
        for index in range(len(myList)):
            resourceType = myList[index].get("resourceType")
            if resourceType == None:
                myList[index]["resourceType"] = "00"
            if resourceType == "01":
                use += float(myList[index]["use"])
                remain += float(myList[index]["remain"])
            if resourceType == "13" or resourceType == "00":
                mlUse += float(myList[index]["use"])            
            if resourceType == "26":
                rbremain += float(myList[index]["remain"])
                rbuse += float(myList[index]["use"])
                if rbremain > 0:
                    state = True
                else: 
                    state = False
        myList = sorted(myList, key=lambda x : int(x['resourceType']))
        use = round(use,2)
        remain = round(remain,2)
        rbuse = round(rbuse,2)
        mlUse = round(mlUse,2)        
        self.flow= {
        	    "use" : use,
        	    "remain" : remain,
        	    "mlUse" : mlUse
        	}
        self.state["riBao"] = state 
        return (use,remain,rbuse,mlUse,state,myList)
                 
    #开通日包
    def ktribao(self):
        state = self.getUse()[4]
        if state == True:
            return False
        now = datetime.date.today()

        this_month_start = datetime.datetime(now.year, now.month, 1)
        this_month_end = datetime.datetime(now.year, now.month, calendar.monthrange(now.year, now.month)[1])
        if str(now) in (str(this_month_start) + str(this_month_end)):
            return self.jihuoLibao()
        else:
            return self.dhrb()  
        
    #以下工具函数
    #字典访问处理数据
    def traversalDict_func(self,dict_a,temp_key,keyList,valueList):
        temp_value = dict_a[temp_key]
        if isinstance(temp_value,list):
            if temp_key in keyList:
                valueList.extend(temp_value)                             
        else:
            if temp_key in keyList:
                valueList.append(temp_value)                     
    def traversalDict(self,dict_a,keyList,valueList,func):
        #使用isinstance检测数据类型 
        if isinstance(dict_a,dict) :
            for x in range(len(dict_a)):           
                temp_key = list(dict_a.keys())[x]
                temp_value = dict_a[temp_key]
                func(dict_a,temp_key,keyList,valueList)
                self.traversalDict(dict_a[temp_key],keyList,valueList,func)
        elif isinstance(dict_a,list) :
            for x in range(len(dict_a)):
                self.traversalDict(dict_a[x],keyList,valueList,func)    
        
                    
    def findAll(self,text,myList):
        
        text0 = text.replace("\n","").replace("\r","").replace("\t","").replace(" ","")
        with open("2.txt",mode="w+") as f:
            f.write(text)
        list0 = []
        list1 = []
        for index in range(len(myList)):
            if index%2==0:
                text = text0
                list1 = []
                start = myList[index]
                end = myList[index+1]
                while(text.find(start) > -1):
                    text1 = text[text.find(start): ]
                    text2 = text1[text1.find(start) + len(start) : text1.find(end)]
                    text = text[text.find(start) + len(start): ]
                    if text2 != "":
                        list1.append(text2)
                list0.append(list1)
                
        return list0